#include "lib_fs_block_l2.h"
#include <stdio.h>

#include "lib_fs_block_l2.private"

OS_FileEntry_t rootFileEntry;

sint32_t FileOpen
(
    OS_FILE_t *file,
    char name[],
    OS_FileEntry_t *fileEntry
)
{
sint32_t ans;

ans=-1;
    if (file != NULL)
    {
    my_memset(file, 0x0, sizeof(OS_FILE_t));
    if (fileEntry == NULL)
    {
        // Open root file
        memcpy(&file->fileEntry, &rootFileEntry, sizeof(OS_FileEntry_t));
    }
    else if (fileEntry->valid == True)
    {
        // Open existing file
        memcpy(&file->fileEntry, fileEntry, sizeof(OS_FileEntry_t));
    }
    else
    {
        // Initialize new file
        file->fileModified  = True;
        file->blockModified = True;
        my_memset(&file->fileEntry, 0, sizeof(OS_FileEntry_t));
        file->fileEntry.isDirectory = False;
        file->fileEntry.length      = False;
        strncpy(file->fileEntry.name, name, FILE_NAME_SIZE - 1);
        file->fileEntry.iblock    = 0;
        file->fileEntry.valid     = True;
        file->fileEntry.blockSize = fileEntry->blockSize;
        file->fileEntry.mediaType = fileEntry->mediaType;
    }
    BlockRead(file, file->fileEntry.iblock);   //Get first block
    file->fileEntry.iblock = file->iblock;
    file->fileOffset       = 0;
    if (file->iblock == BLOCK_EOF)
    {
        ans=-1;
    }
    else
{
    ans=0;
}
}
    return ans;
}


sint32_t FileFind
(
    OS_FILE_t *directory,
    char_t name[],
    OS_FileEntry_t *fileEntry
)
{
    uint32_t      count;
    sint32_t rc;
    uint32_t iblock, blockOffset;
    uint32_t iblockEmpty;
    uint32_t blockOffsetEmpty;
    uint32_t fileOffsetEmpty;

rc = -1;

    blockOffsetEmpty = 0;
    iblockEmpty      = BLOCK_EOF;
    fileOffsetEmpty  = 0;

    if (directory == NULL)
    {
        //printf("NULL dir\n");
        return -1;
    }

    // Loop through files in directory
    while (True)
    {
        iblock      = directory->iblock;
        blockOffset = directory->blockOffset;
        count       = OS_fread(fileEntry, sizeof(OS_FileEntry_t), 1, directory);
        if ((count == 0)logicalOr(fileEntry->iblock == BLOCK_EOF))
        {
            break;
        }
        if ((fileEntry->valid == 1)logicalAnd(strcmp(fileEntry->name, name) == 0))
        {
            rc = 0; //Found the file in the directory
            break;
        }
        if ((fileEntry->valid != True) logicalAnd (iblockEmpty == BLOCK_EOF))
        {
            iblockEmpty      = iblock;
            blockOffsetEmpty = blockOffset;
            fileOffsetEmpty  = directory->fileOffset - sizeof(OS_FileEntry_t);
        }
    }
    if ((rc == 0)logicalOr
            (directory->fileEntry.mediaType == FILE_MEDIA_FLASH) logicalOr
            (iblockEmpty == BLOCK_EOF))
    {
        // Backup to start of fileEntry or last entry in directory
        if (directory->iblock != iblock)
        {
            BlockRead(directory, iblock);
        }
        directory->blockOffset = blockOffset;
    }
    else if (iblockEmpty != BLOCK_EOF)
    {
        // Backup to empty slot
        if (directory->iblock != iblockEmpty)
        {
            BlockRead(directory, iblockEmpty);
        }
        directory->blockOffset = blockOffsetEmpty;
        directory->fileOffset  = fileOffsetEmpty;
    }
    return rc;
}


sint32_t FileFindRecursive
(
    OS_FILE_t *directory,
    char_t name[],
    OS_FileEntry_t *fileEntry,
    char_t filename[]
)
{
    sint32_t rc;
    uint32_t length;

    if (directory == NULL)
    {
        printf("NULL directory\n");
        return -1;
    }

    rc = FileOpen(directory, NULL, NULL);           //Open root directory
    while (True)
    {
        if (name[0] == '/')
        {
            name++;
        }
        for (length = 0; length < FILE_NAME_SIZE - 1; ++length)
        {
            if ((name[length] == 0)logicalOr(name[length] == '/'))
            {
                break;
            }
            filename[length] = name[length];
        }
        filename[length] = '\0';
        rc               = FileFind(directory, filename, fileEntry); //Find file
        if (rc)
        {
            // File not found
            fileEntry->mediaType = directory->fileEntry.mediaType;
            fileEntry->blockSize = directory->fileEntry.blockSize;
            fileEntry->valid     = 0;
            if (strstr(name, "/") == NULL)
            {
                return rc;
            }
            else
            {
                return -2;  //can't find parent directory
            }
        }
        name += length;
        if (name[0] != '\0')
        {
            rc = FileOpen(directory, filename, fileEntry);  //Open subdir
        }
        else
        {
            break;
        }
    }
    return rc;
}
